package com.haredot.config;

import com.haredot.filter.BearerTokenAuthorizationFilter;
import com.haredot.properties.JwtProperties;
import com.haredot.security.JsonAccessDeniedHandler;
import com.haredot.security.JsonAuthenticationEntryPoint;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;

import javax.annotation.Resource;
import java.util.List;

@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@EnableConfigurationProperties(JwtProperties.class)
public class SecurityConfig {

    @Resource
    private JwtProperties jwtProperties;

    @Bean
    public UserDetailsService userDetailsService() {
        return new InMemoryUserDetailsManager();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // 要求所有的请求必须 认证后才能访问
        http.authorizeHttpRequests()
                .antMatchers("/preview", "/test").permitAll()
                .anyRequest()
                .authenticated();

        // 该系统 禁止产生登录页面
        http.formLogin().disable();

        http.exceptionHandling()
                .authenticationEntryPoint(new JsonAuthenticationEntryPoint()) // 没有登录，返回 没认证提示
                .accessDeniedHandler(new JsonAccessDeniedHandler());  // 如果没有权限，返回 403 禁止访问提示


        http.csrf().disable(); // 禁用 CSRF 保护

        http.cors()
                .configurationSource(request -> {
                    CorsConfiguration corsConfiguration = new CorsConfiguration();
                    corsConfiguration.setAllowedOriginPatterns(List.of("*"));
                    corsConfiguration.setAllowedMethods(List.of("*"));
                    corsConfiguration.setAllowedHeaders(List.of("*"));
                    return corsConfiguration;
                });  // 指定跨域请求的配置

        // 配置 session 创建策略 STATELESS 适用于 前后端分离
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);


        http.addFilterBefore(new BearerTokenAuthorizationFilter(jwtProperties), UsernamePasswordAuthenticationFilter.class);


        return http.build();
    }
}
